package com.kelvem.saas.workbanch.ontology.piaoorder.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.kelvem.saas.workbanch.core.base.BaseController;
import com.kelvem.saas.workbanch.fsm.container.DaoContainer;
import com.kelvem.saas.workbanch.fsm.dao.BaseDao;
import com.kelvem.saas.workbanch.fsm.entity.Entity;
import com.kelvem.saas.workbanch.fsm.entity.FsmEventReq;
import com.kelvem.saas.workbanch.ontology.order.request.OrderPaymentReq;
import com.kelvem.saas.workbanch.ontology.piaoorder.dao.PiaoOrderDao;
import com.kelvem.saas.workbanch.ontology.piaoorder.enums.PiaoOrderEventEnum;
import com.kelvem.saas.workbanch.ontology.piaoorder.model.PiaoOrderAddressEntity;
import com.kelvem.saas.workbanch.ontology.piaoorder.model.PiaoOrderEntity;
import com.kelvem.saas.workbanch.ontology.piaoorder.model.PiaoOrderGoodsEntity;
import com.kelvem.saas.workbanch.ontology.piaoorder.request.PiaoOrderReq;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @author kelvem
 */
@RestController
@RequestMapping("/piaoorder")
@Slf4j
public class PiaoOrderController extends BaseController {

    @Resource
    private PiaoOrderDao piaoOrderDao;
    
    @RequestMapping("/create")
    // http://localhost:9090/piaoorder/create
    public String create(@RequestBody PiaoOrderReq order) {
        log.info("create start");
        super.trigger(PiaoOrderEntity.class, PiaoOrderEventEnum.order_create.getEventCode(), order);
        log.info("create end");
        return "create";
    }

    // todo error 有问题, 如果访问, 需要修复
    @RequestMapping("/query")
    // http://localhost:9090/piaoorder/query
    public Collection query(@RequestBody PiaoOrderReq req) {
        
        log.info("query start, customerId=" + req.getCustomerId());
        log.info("query piaoOrderDao : " + piaoOrderDao);

        LambdaQueryWrapper<PiaoOrderEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(PiaoOrderEntity::getCustomerId, req.getCustomerId());
        lambdaQueryWrapper.orderByDesc(PiaoOrderEntity::getId);
        List<PiaoOrderEntity> piaoOrderList = piaoOrderDao.selectList(lambdaQueryWrapper);
        Map<Long, Map<String, List>> bufMap = create(piaoOrderList);
        log.info("query, order.size=" + bufMap.size());
    
        BaseDao piaoOrderAddressDao = DaoContainer.getDao(PiaoOrderAddressEntity.class);
        List<PiaoOrderAddressEntity> piaoOrderAddressList = piaoOrderAddressDao.selectList(new LambdaQueryWrapper<PiaoOrderAddressEntity>());
        merge(bufMap, piaoOrderAddressList, "piaoOrderId");
    
        BaseDao piaoOrderGoodsDao = DaoContainer.getDao(PiaoOrderGoodsEntity.class);
        List<PiaoOrderGoodsEntity> piaoOrderGoodsList = piaoOrderGoodsDao.selectList(new LambdaQueryWrapper<PiaoOrderGoodsEntity>());
        merge(bufMap, piaoOrderGoodsList, "piaoOrderId");
    
        Collection<Map<String, List>> result = bufMap.values();
        log.info("query, result=" + result);
        log.info("query end");
        
        return result;
    }
    
    private Map<Long, Map<String, List>> create (List<? extends Entity> leftList) {
        Map<Long, Map<String, List>> result = new LinkedHashMap<>();
    
        if (leftList != null && leftList.size() <= 0) {
            return result;
        }
        
        for (Entity leftEntity :
                leftList) {
            String entityKey = leftEntity.getClass().getSimpleName();
            List refList = new ArrayList();
            refList.add(leftEntity);
            Map refMap = new LinkedHashMap<String, List>();
            refMap.put(entityKey, refList);
            result.put(leftEntity.getId(), refMap);
        }
        return result;
    }
    private void merge(Map<Long, Map<String, List>> result, List<? extends Entity> rightList, String rightKey) {
        
        if (rightList != null && rightList.size() <= 0) {
            return;
        }
        
        for (Entity rightEntity :
                rightList) {
            try {
                String entityKey = rightEntity.getClass().getSimpleName();
                Field field = null;
                try {
                    field = rightEntity.getClass().getField(rightKey);
                } catch (Exception e1) {
                    field = rightEntity.getClass().getDeclaredField(rightKey);
                }
                field.setAccessible(true);
                Long rightRefId = (Long)field.get(rightEntity);
                Map<String, List> refMap = result.get(rightRefId);
                if (refMap == null) {
                    log.warn("refMap is null, rightRefId=" + rightRefId + " rightEntity=" + rightEntity);
                    continue;
                }
                if (!refMap.containsKey(entityKey)) {
                    refMap.put(entityKey, new ArrayList());
                }
                List refList = refMap.get(entityKey);
                refList.add(rightEntity);
                refMap.put(entityKey, refList);
                
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
    }
    
    @RequestMapping("/cancel")
    public String cancel(@RequestBody FsmEventReq req) {
        super.trigger(PiaoOrderEntity.class, PiaoOrderEventEnum.order_cancel.getEventCode(), req);
        return "cancel";
    }
    
    @RequestMapping("/event/{eventName}")
    public String event(@PathVariable String eventName, @RequestBody FsmEventReq req) {
        log.info("event.eventName=" + eventName);
        super.trigger(PiaoOrderEntity.class, PiaoOrderEventEnum.valueOf(eventName).getEventCode(), req);
        return eventName;
    }
    
    @RequestMapping("/payment")
    public String payment(@RequestParam OrderPaymentReq payment) {
        super.trigger(PiaoOrderEntity.class, PiaoOrderEventEnum.order_payment.getEventCode(), payment);
        return "payment";
    }
    
    @RequestMapping("/purchase")
    public String purchase() {
        return "purchase";
    }
    
    @RequestMapping("/shipping")
    public String shipping() {
        return "shipping";
    }
    
    @RequestMapping("/received")
    public String received() {
        return "received";
    }
    
    @RequestMapping("/directShipping")
    public String directShipping() {
        return "directShipping";
    }
    
}
